/**
 * Promise A+ 规范的实现  - v1.0.0
 * @module Promise
 * git 地址
 * 版权/证书
 */

(function() {
	'use strict';
	var f, g = [];

	function l(a) {
		g.push(a);
		1 == g.length && f()
	}

	function m() {
		for (; g.length;) g[0](), g.shift()
	}
	f = function() {
		setTimeout(m)
	};

	function n(a) {
		this.a = p;
		this.b = void 0;
		this.f = [];
		var b = this;
		try {
			a(function(a) {
				q(b, a)
			}, function(a) {
				r(b, a)
			})
		} catch (c) {
			r(b, c)
		}
	}
	var p = 2;

	function t(a) {
		return new n(function(b, c) {
			c(a)
		})
	}

	function u(a) {
		return new n(function(b) {
			b(a)
		})
	}

	function q(a, b) {
		if (a.a == p) {
			if (b == a) throw new TypeError;
			var c = !1;
			try {
				var d = b && b.then;
				if (null != b && "object" == typeof b && "function" == typeof d) {
					d.call(b, function(b) {
						c || q(a, b);
						c = !0
					}, function(b) {
						c || r(a, b);
						c = !0
					});
					return
				}
			} catch (e) {
				c || r(a, e);
				return
			}
			a.a = 0;
			a.b = b;
			v(a)
		}
	}

	function r(a, b) {
		if (a.a == p) {
			if (b == a) throw new TypeError;
			a.a = 1;
			a.b = b;
			v(a)
		}
	}

	function v(a) {
		l(function() {
			if (a.a != p)
				for (; a.f.length;) {
					var b = a.f.shift(),
						c = b[0],
						d = b[1],
						e = b[2],
						b = b[3];
					try {
						0 == a.a ? "function" == typeof c ? e(c.call(void 0, a.b)) : e(a.b) : 1 == a.a && ("function" == typeof d ? e(d.call(void 0, a.b)) : b(a.b))
					} catch (h) {
						b(h)
					}
				}
		})
	}
	n.prototype.g = function(a) {
		return this.c(void 0, a)
	};
	n.prototype.c = function(a, b) {
		var c = this;
		return new n(function(d, e) {
			c.f.push([a, b, d, e]);
			v(c)
		})
	};

	function w(a) {
		return new n(function(b, c) {
			function d(c) {
				return function(d) {
					h[c] = d;
					e += 1;
					e == a.length && b(h)
				}
			}
			var e = 0,
				h = [];
			0 == a.length && b(h);
			for (var k = 0; k < a.length; k += 1) u(a[k]).c(d(k), c)
		})
	}

	function x(a) {
		return new n(function(b, c) {
			for (var d = 0; d < a.length; d += 1) u(a[d]).c(b, c)
		})
	};
	window.Promise || (window.Promise = n, window.Promise.resolve = u, window.Promise.reject = t, window.Promise.race = x, window.Promise.all = w, window.Promise.prototype.then = n.prototype.c, window.Promise.prototype["catch"] = n.prototype.g);
}());
